﻿/*
 * Vector3.h
 *
 *  Created on: 2011/06/22
 *      Author: naoki
 */

#ifndef INCLUDED_NTENGINE_MATH_VECTOR3_H
#define INCLUDED_NTENGINE_MATH_VECTOR3_H

namespace NTEngine {
namespace Math {

/**
 * @brief 3Dベクタクラス
 *       二項演算子は新しいベクタを生成しなければならんのでサポートしない
 *       だいたい3倍の速度差がでた
 *       代わりにset～系のメソッドを用意
 *       Vector3同士を*すると内積を計算
 */
class Vector3 {
public:
	float x, y, z;

	Vector3(){ }
	Vector3( float xyz );
	Vector3( float x, float y, float z );
	Vector3( const Vector3& );

	Vector3& operator=( const Vector3& );
	Vector3 operator-() const;
	void operator+=( const Vector3& );
	void operator-=( const Vector3& );
	void operator*=( float );
	void operator/=( float );
	float operator*( const Vector3& ) const; // 内積
	float& operator[]( int i );
	float operator[]( int i ) const;
	bool operator==( const Vector3& ) const;
	bool operator!=( const Vector3& ) const;

	/**
	 * @brief ベクタをゼロに設定します
	 */
	void zero();

	/**
	 * @brief ベクタを正規化します
	 */
	void normalize();

	/**
	 * @brief ベクタの大きさです
	 */
	float length() const;

	/**
	 * @brief ベクタの大きさの２乗を取得します
	 */
	float squareLength() const;

	/**
	 * @brief ベクタを再設定します
	 */
	void set( float ax, float ay, float az );

	/**
	 * @brief ベクタa,bの和を計算し、設定します
	 */
	void setAdd( const Vector3& a, const Vector3& b );

	/**
	 * @brief ベクタaの各成分にtを加えたものを設定します
	 */
	void setAdd( const Vector3&, float );

	/**
	 * @brief ベクタa,bの差を計算し、設定します
	 */
	void setSub( const Vector3& a, const Vector3& b );

	/**
	 * @brief ベクタaの各成分にtを引いたものを設定します
	 */
	void setSub( const Vector3&, float );

	/**
	 * @brief ベクタaの各成分にtを乗算したものを設定します
	 */
	void setMul( const Vector3&, float );

	/**
	 * @brief ベクタa,bの乗算を計算し、設定します
	 */
	void setMul( const Vector3&, const Vector3& );

	/**
	 * @brief ベクタa,bの外積を計算し、設定します
	 */
	void setCross( const Vector3& a, const Vector3& b );

	/// this += a * b
	void madd( const Vector3& a, float b );
	void madd( const float* a, float b );
	/// this -= a * b
	void msub( const Vector3& a, float b );
};

extern const Vector3 ZERO_VECTOR3; //!< グローバルなゼロベクタ

} // namespace Math
} // namespace NTEngine

#endif // INCLUDED_NTENGINE_MATH_VECTOR3_H
